//
//  ProjectWindowController.m
//  iCodeMac
//
//  Created by Andrew Barry on 27/03/09.
//  Copyright 2009 Barry Computer Services. All rights reserved.
//

#import "ProjectWindowController.h"
#import "JavascriptProject.h"
#import "WrappedJsval.h"
#import "form.h"

extern NSMutableDictionary *projectPropertiesDefn;

NSString *buildRelativePath(NSString *baseFolder, NSString * path);

@implementation ProjectWindowController
-(void)awakeFromNib {	
	NSWindow *window = [self window];

	[window setDelegate:[self retain]];
	
	[outline setTarget:self];
	[outline setDoubleAction:@selector(outlineDoubleClick:)];

	JavascriptProject *project = [self document];
	NSRect f;
	if ([project savedFrame: &f forWindow: @"!"]) {
		[window setFrame: f display:YES];
	}
	
	projectWindow = [[WrappedJsval wrap: bindForm(mainContext, window) withContext: mainContext] retain];
}

-(NSString *)windowTitleForDocumentDisplayName:(NSString *)displayName {
	JavascriptProject *project = [self document];

	if ([project isDebugging]) {
		if ([project isStopped])
			return [displayName stringByAppendingString:@" - Stopped"];
		else
			return [displayName stringByAppendingString:@" - Running"];
	}
	return displayName;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)parent {
	JavascriptProject *project = [self document];
	id item = [[project items] objectAtIndex:index];
	return item;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
	return NO;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
	JavascriptProject *project = [self document];

	return [[project items] count];
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
	NSString *name;
	if ([item isKindOfClass:[NSString class]])
		name = item;
	else
		name = [[item objectForKey:@"absolute"] lastPathComponent];
		
	if ([(NSString *) [tableColumn identifier] isEqualToString:@"name"]) {
		return [name stringByDeletingPathExtension];
	} else if ([(NSString *) [tableColumn identifier] isEqualToString:@"kind"]) {
		NSString *extension = [name pathExtension];
		if ([extension isEqualToString: @"js"])
			return @"Source";
		else if ([extension isEqualToString: @"jsfrm"])
			return @"Form";
		else if ([extension isEqualToString: @"png"])
			return @"Image";
		else if ([extension isEqualToString: @"icns"])
			return @"Icon";
		else
			return extension;
	}
	return @"";
}

-(void) openRow: (int) row {
	JavascriptProject *project = [self document];
	NSArray *items = [project items];

	if (row >= 0 && row < [items count]) {
		NSString *path = [project pathForItemIndex:row];
		NSURL *projURL = [project fileURL];
		if ([projURL isFileURL]) {
			NSURL *docURL = [NSURL fileURLWithPath:path];
			NSString *ext = [path pathExtension];
			
			if ([ext isEqualToString:@"js"] ||
				[ext isEqualToString:@"jsfrm"])
				[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:docURL display:YES error: nil];
			else
				[[NSWorkspace sharedWorkspace] openFile: path];
		}
	}
}

-(void)outlineDoubleClick:(id) sender {
	[self openRow: [outline clickedRow]];
}

-(void)addExistingFile: (id) sender {
	JavascriptProject *project = [self document];
	NSOpenPanel *panel = [NSOpenPanel openPanel];
	[panel setTitle:@"Add Existing"];
	[panel setDirectory:[project projectFolder]];
	if (NSFileHandlingPanelOKButton == [panel runModalForTypes:[NSArray arrayWithObjects:@"js", @"jsfrm", @"png", @"icns", nil]]) {
		NSString *path = [panel filename];
		NSString *pathFolder = [path stringByDeletingLastPathComponent];
		if ([pathFolder isEqualToString:[project projectFolder]]) {
			[self addProjectFile:[path lastPathComponent]];
		} else {
			NSMutableDictionary *pathItem = [NSMutableDictionary new];
			[pathItem setObject:[NSString stringWithString: path] forKey:@"absolute"];
			[pathItem setObject:buildRelativePath([project projectFolder], path) forKey:@"relative"];
			
			[self addProjectFile:pathItem];
		}

	}
}

-(void)removeProjectFile:(NSNumber *) idxObj {
	JavascriptProject *project = [self document];
	NSMutableArray *items = [project items];

	int idx = [idxObj intValue];
	NSString *path = [[[items objectAtIndex:idx] retain] autorelease];
	[items removeObjectAtIndex:idx];
	[outline reloadData];
	[[project undoManager] registerUndoWithTarget:self selector:@selector(addProjectFile:) object:path];
}

-(void)addProjectFile:(id) path {
	JavascriptProject *project = [self document];
	NSMutableArray *items = [project items];

	int idx = [items count];
	[items addObject:path];
	[outline reloadData];
	[outline selectRow: idx byExtendingSelection: NO];
	
	[[project undoManager] registerUndoWithTarget:self selector:@selector(removeProjectFile:) object:[NSNumber numberWithInt:idx]];
}

- (void)didEndSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
	[sheet orderOut:self];
}

-(void)projectProperties: (id) sender {
	JavascriptProject *project = [self document];
	WrappedJsval *sys = [WrappedJsval wrap:mainContext->slots[13] withContext:mainContext];
	[sys invoke:@"showProjectProperties" args: [NSArray arrayWithObjects: projectWindow, [[project fileURL] absoluteString], nil]];
/*
	FormLoader *loader = [FormLoader new];
	NSWindow *window = [self window];
	
	NSWindow *wnd = [loader newPanel:projectPropertiesDefn];

	JSObject *wndObj = [loader loadForm:projectPropertiesDefn into:wnd];
	[[WrappedJsval alloc] initWithVal:OBJECT_TO_JSVAL(wndObj)];

	JSString *urlStr = JS_NewStringCopyZ(cx, [[[project fileURL] absoluteString] UTF8String]);
	jsval url = STRING_TO_JSVAL(urlStr);
	JS_SetProperty(cx, wndObj, "project", &url);	
		
	[loader startForm: wndObj];
	
	[NSApp beginSheet:wnd modalForWindow:window modalDelegate:self didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) contextInfo:nil];
	jsval trueVal = BOOLEAN_TO_JSVAL(1);
	JS_SetProperty(cx, wndObj, "_openSheet", &trueVal);
	
*/
}

-(void)addNewFile: (id) sender {
	JavascriptProject *project = [self document];
	NSSavePanel *panel = [NSSavePanel savePanel];
	[panel setTitle:@"Add New Source"];
	[panel setRequiredFileType:@"js"];
	[panel setDirectory:[project projectFolder]];
	if (NSFileHandlingPanelOKButton == [panel runModal]) {
		NSString *path = [panel filename];
		NSString *pathFolder = [path stringByDeletingLastPathComponent];
		
		[@"" writeToFile:path atomically:NO];
		
		if ([pathFolder isEqualToString:[project projectFolder]]) {
			[self addProjectFile:[path lastPathComponent]];
		} else {
			NSMutableDictionary *pathItem = [NSMutableDictionary new];
			[pathItem setObject:[NSString stringWithString: path] forKey:@"absolute"];
			[pathItem setObject:buildRelativePath([project projectFolder], path) forKey:@"relative"];
			
			[self addProjectFile:pathItem];
		}
		
		[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:path] display:YES error:nil];
	}
}

-(void)addNewForm: (id) sender {
	JavascriptProject *project = [self document];
	NSSavePanel *panel = [NSSavePanel savePanel];
	[panel setTitle:@"Add New Form"];
	[panel setRequiredFileType:@"jsfrm"];
	[panel setDirectory:[project projectFolder]];
	if (NSFileHandlingPanelOKButton == [panel runModal]) {
		NSString *path = [panel filename];
		NSString *pathFolder = [path stringByDeletingLastPathComponent];

		[@"" writeToFile:path atomically:NO];
		
		if ([pathFolder isEqualToString:[project projectFolder]]) {
			[self addProjectFile:[path lastPathComponent]];
		} else {
			NSMutableDictionary *pathItem = [NSMutableDictionary new];
			[pathItem setObject:[NSString stringWithString: path] forKey:@"absolute"];
			[pathItem setObject:buildRelativePath([project projectFolder], path) forKey:@"relative"];
			
			[self addProjectFile:pathItem];
		}
		
		[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:path] display:YES error:nil];
	}
}

-(void)windowDidMove:(NSNotification *)notification {
	JavascriptProject *project = [self document];
	NSWindow *window = [self window];
	[project saveFrame:[window frame] forWindow: @"_project"];
}

-(void)windowDidResize:(NSNotification *)notification {
	JavascriptProject *project = [self document];
	NSWindow *window = [self window];
	[project saveFrame:[window frame] forWindow: @"_project"];
}

-(void)showBuildSheet {
	NSWindow *window = [self window];
	
    [NSApp beginSheet:buildingSheet modalForWindow:window modalDelegate:self didEndSelector:NULL contextInfo:nil];
	[buildingIndicator startAnimation:nil];
}

-(void)clearBuildSheet {
	[buildingIndicator stopAnimation:nil];
	[buildingSheet orderOut:nil];
    [NSApp endSheet:buildingSheet];
}

-(void) delete: (id) sender {
	int row = [outline selectedRow];
	if (row >= 0) {
		[self removeProjectFile:[NSNumber numberWithInt:row]];
	}
}

-(void) keyDown: (NSEvent *) theEvent {
	int keyCode = [theEvent keyCode];
	int dx, dy;
	dx = dy = 0;
	switch (keyCode) {
		case 36:
		{
			int row = [outline selectedRow];
			[self openRow:row];
			break;
		}
		case 51:
		{
			[self delete: self];
			return;
		}
			break;
	}
	printf("key is %d\n", keyCode);
}

@end
